#include <string>
#include <ncurses.h>
#include "libncursescpp.h"

Window::Window(int xSize, int ySize, int xPos, int yPos)
{
    int maxX, maxY;
    getmaxyx(stdscr, maxY, maxX);

    if (xSize == 0) {
        xSize = maxX;
    } else if (xSize < 0) {
        xSize += maxX;
    }

    if (ySize == 0) {
        ySize = maxY;
    } else if (ySize < 0) {
        ySize += maxY;
    }

    if (xPos < 0) {
        xPos += maxX;
    }

    if (yPos < 0) {
        yPos += maxY;
    }

    this->window = newwin(ySize, xSize, yPos, xPos);
    keypad(this->window, TRUE);
}

Window::~Window()
{
    delwin(this->window);
}

void
ncursesInit()
{
    initscr();
    curs_set(0);
    keypad(stdscr, TRUE);
    noecho();
    raw();
    start_color();
}

void
ncursesEnd()
{
    endwin();
}

int
Window::getNumCols()
{
    int numRows, numCols;
    getmaxyx(this->window, numRows, numCols);
    return numCols;
}

int
Window::getNumRows()
{
    int numRows, numCols;
    getmaxyx(this->window, numRows, numCols);
    return numRows;
}

int
Window::getXPos()
{
    int x, y;
    getyx(this->window, y, x);
    return x;
}

int
Window::getYPos()
{
    int x, y;
    getyx(this->window, y, x);
    return y;
}

void
Window::refresh()
{
    wrefresh(this->window);
}

void
Window::clear()
{
    werase(this->window);
}

void
Window::move(int xPos, int yPos)
{
    wmove(this->window, yPos, xPos);
}

void
Window::print(std::string str)
{
    wprintw(this->window, str.c_str());
}

char
Window::getChar()
{
    char ch = wgetch(this->window);
}

std::string
Window::getString()
{
    char *str;
    wgetstr(this->window, str);

    return *(new std::string(str));
}

void
Window::setAttribute(attr_t attribute)
{
    wattron(this->window, attribute);
}

void
Window::removeAttribute(attr_t attribute)
{
    wattroff(this->window, attribute);
}

void
Window::setColor(int xPos, int yPos, int colorPair)
{
    mvwchgat(this->window, yPos, xPos, 1, A_NORMAL, colorPair, NULL);
}

void
Window::setRowColor(int row, int colorPair)
{
    mvwchgat(this->window, row, 0, -1, A_NORMAL, colorPair, NULL);
}

unsigned long long _colorPairCount_ = 1;
int
getColorPair(int foreground, int background)
{
    int colorPair = _colorPairCount_++;
    init_pair(colorPair, foreground, background);

    return colorPair;
}

void
Window::suspend()
{
    def_prog_mode();
    endwin();
}

void
Window::resume()
{
    reset_prog_mode();
    refresh();
}

